﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;

//*******************************************************************
// Purpose:  Windows.Forms.Form dung de goi cac thu tuc va ham long running trong 1 thread
// Notes:    Người sử dụng sẽ trao vào AddressOf thủ tục, thủ tục có tham số hoặc function để chạy
//           Hỗ trợ thay đổi Description
//           - Properties:
//                ThreadFunction: AddressOf hàm 
//                ThreadSub: AddressOf thủ tục có tham số
//                Thread: AddressOf thủ tục không có tham số
// History:
//     [Programer]       [DD-MMM-YYYY]       [Action]
//     LuanNH            09-May-2007         Created
//*******************************************************************  

    public class frmProgress : Form
    {
        public frmProgress()
        {
            InitializeComponent();
            //
            SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            this.BackColor = Color.Transparent;
            //
            Activated += frmProgress_Activated;
        }
        #region "Contructor"

        private static frmProgress _instance;
        //// Note: Constructor is 'protected'
        //Protected Sub New()
        //End Sub
        //// Note: Dispose is 'protected'
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }
        //protected new void Dispose()
        //{
        //    _instance.Dispose();
        //    _instance = null;
        //    base.Dispose();
        //}
        //// Lock synchronization object
        private static object _syncLock = new object();
        // return the provider
        public static frmProgress Instance()
        {
            //// Support multithreaded applications through
            //// 'Double checked locking' pattern which (once
            //// the instance exists) avoids locking each
            //// time the method is invoked 
            if (_instance == null)
            {
                lock (_syncLock)
                {
                    if (_instance == null)
                    {
                        _instance = new frmProgress();
                        _instance.Tag = "MAIN_INIT";
                    }
                }
            }
            return _instance;
        }
        #endregion

        private FunctionInvoker _ThreadFunction;
        private SubInvoker _ThreadSub;

        private MethodInvoker _ThreadMethod;
        public object ThreadInputObject;
        private object _ThreadOutputObject;
        //
        private System.Threading.Thread m_objThread;
        //
        private string m_sTextDescription;
        private string m_sTextFinish;
        //
        private Exception m_TheardException;
        private string m_sErrorRaise;
        //
        // Define the CS_DROPSHADOW constant

        private const int CS_DROPSHADOW = 131072;
        // Override the CreateParams property
        protected override System.Windows.Forms.CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                //cp.ClassStyle = cp.ClassStyle | CS_DROPSHADOW;
                return cp;
            }
        }
        //

        public FunctionInvoker ThreadFunction
        {
            set
            {
                _ThreadFunction = value;
                _ThreadSub = null;
                _ThreadMethod = null;
                _ThreadOutputObject = null;
            }
        }

        public SubInvoker ThreadSub
        {
            set
            {
                _ThreadSub = value;
                _ThreadFunction = null;
                _ThreadMethod = null;
            }
        }

        public MethodInvoker Thread
        {
            set
            {
                _ThreadMethod = value;
                _ThreadSub = null;
                _ThreadFunction = null;
            }
        }

        public bool IsAbort
        {
            get
            {
                bool bStop = Globals.Object_GetValue<bool>(AppDomain.CurrentDomain.GetData("Progress_Abort"));
                return bStop;
            }
        }

        private bool _IsRunning;
        public bool IsRunning
        {
            get { return _IsRunning; }
        }

        //*******************************************************************
        // Purpose:  hàm Public để show progress
        // Notes:    Trong trường hợp hỗ trợ cancel thì phải có đoạn handle ThreadAbortException để xử lý
        //     - Inputs: 
        //               sDescription : init description text
        //               bAllowCancel : hỗ trợ cancel hay không
        //     - Return: Trả lại kết quả tính toán của ThreadFunction (nếu có)
        // History:
        //     [Programer]       [DD-MMM-YYYY]       [Action]
        //     LuânNH            09-May-2007         Created
        //     [Modifier]        [Modify Date]       Updated
        //*******************************************************************  
        internal object Show_Progress(string sStart, string sFinish)
        {
            m_sTextFinish = sFinish;
            return Show_Progress(sStart, false);
        }

        internal object Show_Progress()
        {
            m_sTextFinish = "";
            return Show_Progress("Loading ...", false);
        }

        internal object Show_Progress(string sStart)
        {
            m_sTextFinish = "";
            return Show_Progress(sStart, false);
        }

        internal object Show_Progress(string sStart, bool bAllowCancel)
        {
            //Prevent wrong call
            if (_ThreadMethod == null & _ThreadSub == null & _ThreadFunction == null)
            {
                throw new Exception("Nothing method or function assigned");
            }
            //Prevent wrong call
            if (this.Visible || (m_objThread != null))
            {
                if ((_ThreadFunction != null))
                {
                    throw new Exception("Progress is running");
                }
                else
                {
                    //Support call method in progress
                    Dummy_Function();
                    return null;
                }
            }
            _IsRunning = true;
            try
            {
                //m_sErrorRaise = "Init_Circle"
                Init_Circle(this.LoadingCircle);
                Init_Thread();
                //
                //m_sErrorRaise = "SetDescription"
                //
                if (string.IsNullOrEmpty(sStart))
                {
                    sStart = "Loading ...";
                }
                else
                {
                    if (!sStart.EndsWith("..."))
                    {
                        sStart += " ...";
                    }
                }
                m_sTextDescription = sStart;
                SetDescription();
                //
                cmdCancel.Visible = bAllowCancel;
                m_TheardException = null;
                //
                if (!bAllowCancel)
                {
                    this.Width = 240;
                }
                //
                //m_sErrorRaise = "ShowDialog"
                //
                this.Tag = "MAIN_PROGRESS";
                this.TopMost = false;
                this.Timer_Event.Enabled = false;
                this.ShowInTaskbar = false;
                //
                //if (this.Owner != FormGlobals.GetActiveForm())
                //if(this.Owner!=Form.ActiveForm)
                //this.Owner = Form.ActiveForm;

                
                this.ShowDialog();
                //
                if (m_objThread.ThreadState == System.Threading.ThreadState.Running || m_objThread.ThreadState == System.Threading.ThreadState.WaitSleepJoin)
                {
                    AppDomain.CurrentDomain.SetData("Progress_Stop", true);
                    if (m_objThread.ThreadState == System.Threading.ThreadState.Running)
                    {
                        while (m_objThread.ThreadState != System.Threading.ThreadState.Stopped)
                        {
                            System.Threading.Thread.Sleep(50);
                        }
                    }
                }
                m_objThread.Abort();
                m_objThread = null;
                //
                this.Hide();
                //
                //if (this.Owner != null)
                //{
                //    this.Owner.Activate();
                //    this.Owner.TopMost = true;
                //    this.Owner.TopLevel = true;
                //}
                
                if ((m_TheardException != null))
                {
                    throw m_TheardException;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                throw ex;
                
                //throw Exception(m_sErrorRaise + ": " + ex.Message)
            }
            finally
            {
                m_TheardException = null;
                _IsRunning = false;
            }
            return _ThreadOutputObject;
        }

        private void Init_Thread()
        {
            if ((m_objThread != null))
                m_objThread.Abort();
            m_objThread = new System.Threading.Thread(Show_Circle);
            //m_objThread.IsBackground = True
        }

        private void Init_Circle(LoadingControl lc)
        {
            lc.StylePreset = LoadingControl.StylePresets.Custom;
            lc.OuterCircleRadius = 12;
            lc.InnerCircleRadius = 8;
            lc.NumberSpoke = 12;
            lc.SpokeThickness = 3;
            lc.RotationSpeed = 500 / lc.NumberSpoke;
            lc.Active = false;
        }
        //*******************************************************************
        // Purpose:  hàm Public để set description text
        // Notes:    
        //     - Inputs: 
        //               sDescription : description text
        // History:
        //     [Programer]       [DD-MMM-YYYY]       [Action]
        //     LuânNH            09-May-2007         Created
        //     [Modifier]        [Modify Date]       Updated
        //*******************************************************************  
        public void SetDescriptionText(string sDescription)
        {
            m_sTextDescription = sDescription;
            SetDescription();
        }

        private void SetDescription()
        {
            //If Me.InvokeRequired Then
            //    Me.Invoke(New MethodInvoker(AddressOf SetDescription))
            //Else
            //    'lbDescription.Text = m_sTextDescription
            //    'lbDescription.Refresh()
            //    'Me.Refresh()
            //End If
            lbDescription.Text = m_sTextDescription;
            AppDomain.CurrentDomain.SetData("Progress_Desc", m_sTextDescription);
        }
        //*******************************************************************
        // Purpose:  hàm Public để set Finish description text
        // Notes:    
        //     - Inputs: 
        //               sFinish : chuỗi Finish description text 
        // History:
        //     [Programer]       [DD-MMM-YYYY]       [Action]
        //     LuânNH            09-May-2007         Created
        //     [Modifier]        [Modify Date]       Updated
        //*******************************************************************  
        public void SetFinishText(string sFinish = "Data saved", int iDelay = 1000)
        {
            m_sTextDescription = sFinish;
            SetDescription();
            //Delay iDelay milisecond
            DateTime t = DateTime.Now;
            while ((DateTime.Now - t).TotalMilliseconds < iDelay)
            {
                System.Threading.Thread.Sleep(100);
                Application.DoEvents();
            }
        }

        public void SetVisible(bool bVisible)
        {
            AppDomain.CurrentDomain.SetData("Progress_Visible", bVisible);
            this.Visible = bVisible;
            if (bVisible)
            {
                Init_Thread();
                m_objThread.Start();
                Application.DoEvents();
                System.Threading.Thread.Sleep(200);
            }
            else
            {
                Application.OpenForms[0].Activate();
            }
        }

        //*******************************************************************
        // Purpose:  hàm để gọi trong Thread và Invoke thủ tục hoặc hàm
        // Notes:    
        // History:
        //     [Programer]       [DD-MMM-YYYY]       [Action]
        //     LuânNH            09-May-2007         Created
        //     [Modifier]        [Modify Date]       Updated
        //*******************************************************************  
        private void Dummy_Function()
        {
            try
            {
                if ((_ThreadMethod != null))
                {
                    _ThreadMethod.Invoke();
                }
                else if ((_ThreadSub != null))
                {
                    _ThreadSub.Invoke(ThreadInputObject);
                }
                else if ((_ThreadFunction != null))
                {
                    _ThreadOutputObject = _ThreadFunction.Invoke(ThreadInputObject);
                }
            }
            catch (Exception ex)
            {
                m_TheardException = ex;
            }
            finally
            {
                _ThreadFunction = null;
                _ThreadSub = null;
                _ThreadMethod = null;
            }
        }

        private void cmdCancel_Click(System.Object sender, System.EventArgs e)
        {
            SetDescriptionText("Cancelling ...");
            AppDomain.CurrentDomain.SetData("Progress_Abort", true);
            cmdCancel.Enabled = false;
        }

        private void Timer_Event_Tick(object sender, System.EventArgs e)
        {
            try
            {
                if (Globals.Object_GetValue<string>(this.Tag) == "CHILD")
                {
                    lbDescription.Text = Globals.Object_GetValue<string>(AppDomain.CurrentDomain.GetData("Progress_Desc"));
                    bool bStop = Globals.Object_GetValue<bool>(AppDomain.CurrentDomain.GetData("Progress_Stop"));
                    if (bStop)
                    {
                        this.Hide();
                    }
                    else
                    {
                        bStop = !Globals.Object_GetValue<bool>(AppDomain.CurrentDomain.GetData("Progress_Visible"));
                        if (bStop)
                            this.Hide();
                    }
                    if (bStop)
                        Timer_Event.Enabled = false;
                }
                else if (Globals.Object_GetValue<string>(this.Tag) == "MAIN_PROGRESS")
                {
                    bool bStop = Globals.Object_GetValue<bool>(AppDomain.CurrentDomain.GetData("Progress_Abort"));
                }

            }
            catch
            {
            }
        }

        private void Show_Circle()
        {
            frmProgress f = new frmProgress();
            try
            {
                m_sErrorRaise = "Init Child";
                Init_Circle(f.LoadingCircle);
                f.LoadingCircle.Active = true;
                f.Timer_Event.Interval = 75;
                f.Timer_Event.Enabled = true;
                f.lbDescription.Text = m_sTextDescription;
                f.Tag = "CHILD";
                f.Width = this.Width;
                f.TopMost = this.TopMost;
                f.cmdCancel.Visible = this.cmdCancel.Visible;
                f.cmdCancel.TabStop = false;
                m_sErrorRaise = "Show Child";
                f.ShowInTaskbar = false;
                f.StartPosition = FormStartPosition.Manual;
                f.Location = this.Location;
                //f.TopMost = true;
                f.ShowDialog();
            }
            catch
            {
            }
            finally
            {
                f.Timer_Event.Enabled = false;
                f.LoadingCircle.Active = false;
                f.Close();
            }
        }

        private void frmProgress_Activated(object sender, System.EventArgs e)
        {
            try
            {
                if (Globals.Object_GetValue<string>(this.Tag) == "MAIN_PROGRESS")
                {
                    if (m_objThread == null)
                    {
                        //Throw New Exception("Thread is nothing")
                        this.Close();
                        return;
                    }
                    if (m_objThread.ThreadState == System.Threading.ThreadState.Running || m_objThread.ThreadState == System.Threading.ThreadState.Stopped)
                        return;
                    //
                    AppDomain.CurrentDomain.SetData("Progress_Abort", false);
                    AppDomain.CurrentDomain.SetData("Progress_Stop", false);
                    AppDomain.CurrentDomain.SetData("Progress_Visible", true);
                    //
                    m_sErrorRaise = "Thread start";
                    //
                    m_objThread.Start();
                    //
                    Application.DoEvents();
                    System.Threading.Thread.Sleep(100);
                    //
                    m_sErrorRaise = "Process Function";
                    //
                    Dummy_Function();
                    //
                    if (!string.IsNullOrEmpty(m_sTextFinish))
                    {
                        SetFinishText(m_sTextFinish);
                        m_sTextFinish = "";
                    }
                    //
                    this.Close();
                }
                else
                {
                    Timer_Event.Enabled = true;
                }
            }
            catch (Exception ex)
            {
                m_TheardException = ex;
            }
        }
        //public frmProgress()
        //{

        //}

        internal Timer Timer_Event;
        private IContainer components;
        internal Button cmdCancel;
        public Label lbDescription;

        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.Timer_Event = new System.Windows.Forms.Timer(this.components);
            this.cmdCancel = new System.Windows.Forms.Button();
            this.lbDescription = new System.Windows.Forms.Label();
            this.Panel1 = new System.Windows.Forms.Panel();
            this.LoadingCircle = new LoadingControl();
            this.Panel1.SuspendLayout();
            this.SuspendLayout();
            // 
            // Timer_Event
            // 
            this.Timer_Event.Interval = 50;
            this.Timer_Event.Tick += new System.EventHandler(this.Timer_Event_Tick);
            // 
            // cmdCancel
            // 
            this.cmdCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this.cmdCancel.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
            this.cmdCancel.Location = new System.Drawing.Point(211, 5);
            this.cmdCancel.Name = "cmdCancel";
            this.cmdCancel.Size = new System.Drawing.Size(75, 23);
            this.cmdCancel.TabIndex = 2;
            this.cmdCancel.Text = "Cancel";
            this.cmdCancel.UseVisualStyleBackColor = true;
            this.cmdCancel.Visible = false;
            this.cmdCancel.Click += new System.EventHandler(this.cmdCancel_Click);
            // 
            // lbDescription
            // 
            this.lbDescription.AutoSize = true;
            this.lbDescription.Location = new System.Drawing.Point(38, 10);
            this.lbDescription.Name = "lbDescription";
            this.lbDescription.Size = new System.Drawing.Size(57, 13);
            this.lbDescription.TabIndex = 1;
            this.lbDescription.Text = "Loading ...";
            // 
            // Panel1
            // 
            this.Panel1.BackColor = System.Drawing.Color.WhiteSmoke;
            this.Panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            this.Panel1.Controls.Add(this.LoadingCircle);
            this.Panel1.Controls.Add(this.cmdCancel);
            this.Panel1.Controls.Add(this.lbDescription);
            this.Panel1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.Panel1.Location = new System.Drawing.Point(0, 0);
            this.Panel1.Name = "Panel1";
            this.Panel1.Size = new System.Drawing.Size(292, 36);
            this.Panel1.TabIndex = 1;
            // 
            // LoadingCircle
            // 
            this.LoadingCircle.Active = false;
            this.LoadingCircle.Color = System.Drawing.Color.SteelBlue;
            this.LoadingCircle.Location = new System.Drawing.Point(6, 4);
            this.LoadingCircle.Name = "LoadingCircle";
            this.LoadingCircle.RotationSpeed = 100;
            this.LoadingCircle.Size = new System.Drawing.Size(28, 26);
            this.LoadingCircle.TabIndex = 3;
            this.LoadingCircle.Text = "loadingControl1";
            // 
            // frmProgress
            // 
            this.ClientSize = new System.Drawing.Size(292, 36);
            this.Controls.Add(this.Panel1);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
            this.Name = "frmProgress";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
            this.Activated += new System.EventHandler(this.frmProgress_Activated);
            this.Panel1.ResumeLayout(false);
            this.Panel1.PerformLayout();
            this.ResumeLayout(false);

        }

        internal Panel Panel1;
        private LoadingControl LoadingCircle;
    }


//=======================================================
//Service provided by Telerik (www.telerik.com)
//Conversion powered by NRefactory.
//Twitter: @telerik
//Facebook: facebook.com/telerik
//=======================================================



    //public partial class Progress : Form
    //{
    //    public Progress()
    //    {
    //        InitializeComponent();
    //        //
    //        SetStyle(ControlStyles.SupportsTransparentBackColor, true);
    //        this.BackColor = Color.Transparent;
    //        //
    //        Activated += frmProgress_Activated;
    //    }

    //    private static Progress _instance;
    //    //// Lock synchronization object
    //    private static object _syncLock = new object();
    //    // return the provider
    //    public static Progress Instance()
    //    {
    //        //// Support multithreaded applications through
    //        //// 'Double checked locking' pattern which (once
    //        //// the instance exists) avoids locking each
    //        //// time the method is invoked 
    //        if (_instance == null)
    //        {
    //            lock (_syncLock)
    //            {
    //                if (_instance == null)
    //                {
    //                    _instance = new Progress();
    //                    _instance.Tag = "MAIN_INIT";
    //                }
    //            }
    //        }
    //        return _instance;
    //    }

    //    private FunctionInvoker _ThreadFunction;
    //    private SubInvoker _ThreadSub;

    //    private MethodInvoker _ThreadMethod;
    //    public object ThreadInputObject;
    //    private object _ThreadOutputObject;
    //    //
    //    private System.Threading.Thread m_objThread;
    //    //
    //    private string m_sTextDescription;
    //    private string m_sTextFinish;
    //    //
    //    private Exception m_TheardException;
    //    private string m_sErrorRaise;
    //    //
    //    // Define the CS_DROPSHADOW constant

    //    private const int CS_DROPSHADOW = 131072;
    //    // Override the CreateParams property
    //    protected override System.Windows.Forms.CreateParams CreateParams
    //    {
    //        get
    //        {
    //            CreateParams cp = base.CreateParams;
    //            cp.ClassStyle = cp.ClassStyle | CS_DROPSHADOW;
    //            return cp;
    //        }
    //    }
    //    //

    //    public FunctionInvoker ThreadFunction
    //    {
    //        set
    //        {
    //            _ThreadFunction = value;
    //            _ThreadSub = null;
    //            _ThreadMethod = null;
    //            _ThreadOutputObject = null;
    //        }
    //    }

    //    public SubInvoker ThreadSub
    //    {
    //        set
    //        {
    //            _ThreadSub = value;
    //            _ThreadFunction = null;
    //            _ThreadMethod = null;
    //        }
    //    }

    //    public MethodInvoker Thread
    //    {
    //        set
    //        {
    //            _ThreadMethod = value;
    //            _ThreadSub = null;
    //            _ThreadFunction = null;
    //        }
    //    }

    //    public bool IsAbort
    //    {
    //        get
    //        {
    //            bool bStop = Convert.ToBoolean(AppDomain.CurrentDomain.GetData("Progress_Abort"));
    //            return bStop;
    //        }
    //    }

    //    //Public Overloads Sub Show()
    //    //    If Me.Tag Is Nothing Then
    //    //        Throw New Exception("Use frmProgress.Instance.Show for display progress")
    //    //    End If
    //    //    Me.InitializeComponent()
    //    //    Show_Progress("Loading ...")
    //    //End Sub

    //    //Public Overloads Sub Show(ByVal sDescription As String)
    //    //    If Me.Tag Is Nothing Then
    //    //        Throw New Exception("Use frmProgress.Instance.Show for display progress")
    //    //    End If
    //    //    Me.InitializeComponent()
    //    //    Show_Progress(sDescription)
    //    //End Sub

    //    //Public Overloads Function ShowDialog() As DialogResult
    //    //    If Me.Tag = "MAIN_INIT" Then
    //    //        Throw New Exception("Use method Show instead of ShowDialog on frmProgress.Instance")
    //    //    ElseIf Me.Tag Is Nothing Then
    //    //        Throw New Exception("Use frmProgress.Instance.Show for display progress")
    //    //    End If
    //    //    Return MyBase.ShowDialog()
    //    //End Function

    //    //Public Overloads Function ShowDialog() As DialogResult
    //    //    Me.InitializeComponent()
    //    //    Show_Progress("Loading ...")
    //    //End Function

    //    //Public Overloads Function ShowDialog(ByVal sDescription As String) As DialogResult
    //    //    Me.InitializeComponent()
    //    //    If sDescription = "" Then sDescription = "Loading ..."
    //    //    Show_Progress(sDescription)
    //    //End Function
    //    //*******************************************************************
    //    // Purpose:  hàm Public để show progress
    //    // Notes:    Trong trường hợp hỗ trợ cancel thì phải có đoạn handle ThreadAbortException để xử lý
    //    //     - Inputs: 
    //    //               sDescription : init description text
    //    //               bAllowCancel : hỗ trợ cancel hay không
    //    //     - Return: Trả lại kết quả tính toán của ThreadFunction (nếu có)
    //    // History:
    //    //     [Programer]       [DD-MMM-YYYY]       [Action]
    //    //     LuânNH            09-May-2007         Created
    //    //     [Modifier]        [Modify Date]       Updated
    //    //*******************************************************************  
    //    public object Show_Progress(string sStart, string sFinish)
    //    {
    //        m_sTextFinish = sFinish;
    //        return Show_Progress(sStart, false);
    //    }

    //    public object Show_Progress()
    //    {
    //        m_sTextFinish = "";
    //        return Show_Progress("Loading ...", false);
    //    }

    //    public object Show_Progress(string sStart)
    //    {
    //        m_sTextFinish = "";
    //        return Show_Progress(sStart, false);
    //    }

    //    public object Show_Progress(string sStart, bool bAllowCancel)
    //    {
    //        //Prevent wrong call
    //        if (_ThreadMethod == null & _ThreadSub == null & _ThreadFunction == null)
    //        {
    //            throw new Exception("Nothing method or function assigned");
    //        }
    //        //Prevent wrong call
    //        if (this.Visible || m_objThread != null)
    //        {
    //            if ((_ThreadFunction != null))
    //            {
    //                throw new Exception("Progress is running");
    //            }
    //            else
    //            {
    //                //Support call method in progress
    //                Dummy_Function();
    //                return null;
    //            }
    //        }
    //        try
    //        {
    //            this.ShowInTaskbar = false; //-ko hiển thị lên taskbar của form

    //            //m_sErrorRaise = "Init_Circle"
    //            Init_Circle(this.LoadingCircle);
    //            if ((m_objThread != null))
    //                m_objThread.Abort();
    //            m_objThread = new System.Threading.Thread(Show_Circle);
    //            //
    //            //m_sErrorRaise = "SetDescription"
    //            //
    //            if (string.IsNullOrEmpty(sStart))
    //            {
    //                sStart = "Loading ...";
    //            }
    //            else
    //            {
    //                if (!sStart.EndsWith("..."))
    //                {
    //                    sStart += " ...";
    //                }
    //            }
    //            m_sTextDescription = sStart;
    //            SetDescription();
    //            //
    //            cmdCancel.Visible = bAllowCancel;
    //            m_TheardException = null;
    //            //
    //            if (!bAllowCancel)
    //            {
    //                this.Width = 240;
    //            }
    //            //
    //            //m_sErrorRaise = "ShowDialog"
    //            //
    //            this.Tag = "MAIN_PROGRESS";
    //            this.TopMost = false;
    //            this.Timer_Event.Enabled = false;
    //            this.Owner = Form.ActiveForm;
    //            this.ShowDialog();
    //            //
    //            if (m_objThread.ThreadState == System.Threading.ThreadState.Running || m_objThread.ThreadState == System.Threading.ThreadState.WaitSleepJoin)
    //            {
    //                if (m_objThread.ThreadState == System.Threading.ThreadState.Running)
    //                {
    //                    AppDomain.CurrentDomain.SetData("Progress_Stop", true);
    //                    while (m_objThread.ThreadState != System.Threading.ThreadState.Stopped)
    //                    {
    //                        System.Threading.Thread.Sleep(50);
    //                    }
    //                }
    //                m_objThread.Abort();
    //                m_objThread = null;
    //            }
    //            //
    //            this.Hide();
    //            //
    //            if (this.Owner != null) this.Owner.Activate(); //hiển thị focus lên
    //            //
    //            if ((m_TheardException != null))
    //            {
    //                throw m_TheardException;
    //            }
    //        }
    //        catch (Exception ex)
    //        {
    //            throw ex;
    //            //Throw New Exception(m_sErrorRaise + ": " + ex.Message)
    //        }
    //        finally
    //        {
    //            m_TheardException = null;
    //        }
    //        return _ThreadOutputObject;
    //    }

    //    private void Init_Circle(LoadingControl lc)
    //    {
    //        lc.StylePreset = LoadingControl.StylePresets.Custom;
    //        lc.OuterCircleRadius = 12;
    //        lc.InnerCircleRadius = 8;
    //        lc.NumberSpoke = 12;
    //        lc.SpokeThickness = 3;
    //        lc.RotationSpeed = 500 / lc.NumberSpoke;
    //        lc.Active = false;
    //    }
    //    //*******************************************************************
    //    // Purpose:  hàm Public để set description text
    //    // Notes:    
    //    //     - Inputs: 
    //    //               sDescription : description text
    //    // History:
    //    //     [Programer]       [DD-MMM-YYYY]       [Action]
    //    //     LuânNH            09-May-2007         Created
    //    //     [Modifier]        [Modify Date]       Updated
    //    //*******************************************************************  
    //    public void SetDescriptionText(string sDescription)
    //    {
    //        m_sTextDescription = sDescription;
    //        SetDescription();
    //    }

    //    private void SetDescription()
    //    {
    //        //If Me.InvokeRequired Then
    //        //    Me.Invoke(New MethodInvoker(AddressOf SetDescription))
    //        //Else
    //        //    'lbDescription.Text = m_sTextDescription
    //        //    'lbDescription.Refresh()
    //        //    'Me.Refresh()
    //        //End If
    //        lbDescription.Text = m_sTextDescription;
    //        AppDomain.CurrentDomain.SetData("Progress_Desc", m_sTextDescription);
    //    }
    //    //*******************************************************************
    //    // Purpose:  hàm Public để set Finish description text
    //    // Notes:    
    //    //     - Inputs: 
    //    //               sFinish : chuỗi Finish description text 
    //    // History:
    //    //     [Programer]       [DD-MMM-YYYY]       [Action]
    //    //     LuânNH            09-May-2007         Created
    //    //     [Modifier]        [Modify Date]       Updated
    //    //*******************************************************************  
    //    public void SetFinishText(string sFinish = "Data saved", int iDelay = 1000)
    //    {
    //        m_sTextDescription = sFinish;
    //        SetDescription();
    //        //Delay iDelay milisecond
    //        DateTime t = DateTime.Now;
    //        while ((DateTime.Now - t).TotalMilliseconds < iDelay)
    //        {
    //            System.Threading.Thread.Sleep(100);
    //            Application.DoEvents();
    //        }
    //    }

    //    public void SetVisible(bool bVisible)
    //    {
    //        this.Visible = bVisible;
    //        AppDomain.CurrentDomain.SetData("Progress_Visible", bVisible);
    //    }

    //    //*******************************************************************
    //    // Purpose:  hàm để gọi trong Thread và Invoke thủ tục hoặc hàm
    //    // Notes:    
    //    // History:
    //    //     [Programer]       [DD-MMM-YYYY]       [Action]
    //    //     LuânNH            09-May-2007         Created
    //    //     [Modifier]        [Modify Date]       Updated
    //    //*******************************************************************  
    //    private void Dummy_Function()
    //    {
    //        try
    //        {
    //            if ((_ThreadMethod != null))
    //            {
    //                _ThreadMethod.Invoke();
    //            }
    //            else if ((_ThreadSub != null))
    //            {
    //                _ThreadSub.Invoke(ThreadInputObject);
    //            }
    //            else if ((_ThreadFunction != null))
    //            {
    //                _ThreadOutputObject = _ThreadFunction.Invoke(ThreadInputObject);
    //            }
    //        }
    //        catch (Exception ex)
    //        {
    //            m_TheardException = ex;
    //        }
    //        finally
    //        {
    //            //Me.Invoke(New MethodInvoker(AddressOf Me.Close))
    //        }
    //    }

    //    private void cmdCancel_Click(System.Object sender, System.EventArgs e)
    //    {
    //        SetDescriptionText("Cancelling ...");
    //        AppDomain.CurrentDomain.SetData("Progress_Abort", true);
    //        cmdCancel.Enabled = false;
    //    }

    //    private void Show_Circle()
    //    {
    //        Progress f = new Progress();
    //        try
    //        {
    //            m_sErrorRaise = "Init Child";
    //            Init_Circle(f.LoadingCircle);
    //            f.LoadingCircle.Active = true;
    //            f.Timer_Event.Interval = 75;
    //            f.Timer_Event.Enabled = true;
    //            f.lbDescription.Text = m_sTextDescription;
    //            f.Tag = "CHILD";
    //            f.Width = this.Width;
    //            f.TopMost = this.TopMost;
    //            f.cmdCancel.Visible = this.cmdCancel.Visible;
    //            f.cmdCancel.TabStop = false;
    //            m_sErrorRaise = "Show Child";
    //            f.ShowDialog();
    //        }
    //        catch
    //        {
    //        }
    //        finally
    //        {
    //            f.LoadingCircle.Active = false;
    //            f.Timer_Event.Enabled = false;
    //            f.Close();
    //        }
    //    }

    //    private void frmProgress_Activated(object sender, System.EventArgs e)
    //    {
    //        try
    //        {
    //            if (this.Tag == "MAIN_PROGRESS")
    //            {
    //                if (m_objThread == null)
    //                {
    //                    //Throw New Exception("Thread is nothing")
    //                    this.Close();
    //                    return;
    //                }
    //                if (m_objThread.ThreadState == System.Threading.ThreadState.Running || m_objThread.ThreadState == System.Threading.ThreadState.Stopped)
    //                    return;
    //                //
    //                AppDomain.CurrentDomain.SetData("Progress_Abort", false);
    //                AppDomain.CurrentDomain.SetData("Progress_Stop", false);
    //                AppDomain.CurrentDomain.SetData("Progress_Visible", true);
    //                //
    //                m_sErrorRaise = "Thread start";
    //                //
    //                m_objThread.Start();
    //                //
    //                Application.DoEvents();
    //                System.Threading.Thread.Sleep(100);
    //                //
    //                m_sErrorRaise = "Process Function";
    //                //
    //                Dummy_Function();
    //                //
    //                if (!string.IsNullOrEmpty(m_sTextFinish))
    //                {
    //                    SetFinishText(m_sTextFinish);
    //                    m_sTextFinish = "";
    //                }
    //                //
    //                this.Close();
    //            }
    //            else
    //            {
    //                Timer_Event.Enabled = true;
    //            }
    //        }
    //        catch (Exception ex)
    //        {
    //            m_TheardException = ex;
    //        }
    //    }

    //    private void Timer_Event_Tick(object sender, EventArgs e)
    //    {
    //        try
    //        {
    //            if (this.Tag == "CHILD")
    //            {
    //                lbDescription.Text = AppDomain.CurrentDomain.GetData("Progress_Desc").ToString();
    //                bool bStop = Convert.ToBoolean(AppDomain.CurrentDomain.GetData("Progress_Stop"));
    //                if (bStop)
    //                {
    //                    this.Hide();
    //                }
    //                else
    //                {
    //                    bStop = Convert.ToBoolean(AppDomain.CurrentDomain.GetData("Progress_Visible"));
    //                    this.Visible = bStop;
    //                }
    //            }
    //            else if (this.Tag == "MAIN_PROGRESS")
    //            {
    //                bool bStop = Convert.ToBoolean(AppDomain.CurrentDomain.GetData("Progress_Abort"));
    //            }

    //        }
    //        catch
    //        {
    //        }
    //    }
        
    //}
